package com.example.netty

import com.squareup.moshi.Moshi
import com.squareup.moshi.Types
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
import com.squareup.moshi.rawType
import org.junit.Assert.*
import org.junit.Test
import java.lang.reflect.ParameterizedType
import java.lang.reflect.Type
import java.net.InetSocketAddress
import java.net.ServerSocket

/**
 * Example local unit test, which will execute on the development machine (host).
 *
 * See [testing documentation](http://d.android.com/tools/testing).
 */
class ExampleUnitTest {
    @Test
    fun addition_isCorrect() {
        val server = ServerSocket()
        server.bind(InetSocketAddress("0.0.0.0", 10999))
        println("start accept:${server.localSocketAddress}")
        while (true) {
            val socket = server.accept()
            val address = socket.remoteSocketAddress
            println("接受到新的连接：$address")
        }
    }

    //    private val callback = object : Callback<School> {
//        override fun call(data: School) {
//
//        }
//    }
    private val mycall = object : MyCallback<School>() {
        override fun call(data: School) {

        }
    }

    @Test

    fun testMoshi() {
        val peoples = ArrayList<People>()
        for (i in 0..3) {
            peoples.add(People("luqihua-$i", "man", 20 + i))
        }
        val school = School(peoples)


        val type = mycall.getType()
//        val type = getType(callback = callback)
        println("type = $type")
        val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build()
        val adapter = moshi.adapter<Any>(type)
        val json = adapter.toJson(school)
        println("json = $json")

        val p = adapter.fromJson(json)
        println("#### = $p")
    }

}

//private fun getType(callback: Callback<*>): Type {
//    val types = callback.javaClass.genericInterfaces
//    types.forEach {
//        if (it is ParameterizedType) {
//            val typeArgs = it.actualTypeArguments
//            return typeArgs[0]
//        }
//    }
//    return callback.javaClass
//}


val callback = object : Callback<School> {
    override fun getType(): Type {
        val types = javaClass.genericInterfaces
        types.forEach {
            if (it is ParameterizedType) {
                val typeArgs = it.actualTypeArguments
                return typeArgs[0]
            }
        }
        return Any::class.java
    }

    override fun call(data: School) {

    }
}

abstract class MyCallback<T> {
    fun getType(): Type {
        val parameterizedType = javaClass.genericSuperclass as ParameterizedType
        val typeArgs = parameterizedType.actualTypeArguments
        return typeArgs[0]
    }

    abstract fun call(data: T)
}

interface Callback<T> {
    fun getType(): Type
    fun call(data: T)
}